package com.ost.micro.dynamic;

import net.sf.json.JSONObject;

import java.io.File;
import java.lang.instrument.ClassDefinition;
import java.lang.instrument.Instrumentation;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * 动态修改class文件信息
 */
public class DynamicApplication {

    public static void agentmain(String args, Instrumentation inst) {
        if (null != args) {
            JSONObject jsonObject = JSONObject.fromObject(args);
            List<Class> classList = new ArrayList<>();
            Object filePath = jsonObject.getOrDefault("filePath", "");
            String fileCheck = String.valueOf(jsonObject.getOrDefault("fileCheck", ""));
            List<String> classNameList = (List<String>) jsonObject.getOrDefault("reloadClassList", new ArrayList<>());
            if (null == filePath || "" == filePath || classNameList.isEmpty()) {
                System.out.println("<-------filePath,reloadClassList为空,热加载失败,请检查------>");
            }
            classNameList.forEach(n -> {
                try {
                    classList.add(Class.forName(n));
                } catch (Exception e) {}
            });
            for (Class cls : classList) {
                if (cls.getName().contains(fileCheck)) {
                    try {
                        byte[] bytes = fileToBytes(filePath, cls.getName());
                        ClassDefinition classDefinition = new ClassDefinition(cls, bytes);
                        System.out.println(classDefinition.getDefinitionClass().getClass());
                        inst.redefineClasses(classDefinition);
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("DynamicApplication,agentmain,errorMsg" + e.getMessage());
                    }
                }
            }
        }
    }


    /**
     * 获取class字节数组
     *
     * @param name class name
     * @return byte[]
     */
    public static byte[] fileToBytes(Object filePath, String name) throws Exception {
        return Files.readAllBytes(Paths.get(filePath + name.replace('.', File.separatorChar) + ".class"));
    }
}
